home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / VALUE.H < prev    next >
C/C++ Source or Header  |  1992-08-20  |  9KB  |  356 lines

  1. //
  2. // Copyright (C) 1992 General Electric Company.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // General Electric Company provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12. // Changed: VDN 04/15/92 -- Lice version
  13. //
  14. // Value is a general slot capable of taking void* and all primitive types.
  15. // It is needed to store any value in a property list, and to do conversion.
  16. // If your application has a base class, then you can add pointer to this
  17. // base class as a type of Value, instead of using void*.
  18. //
  19.  
  20. #ifndef VALUEH
  21. #define VALUEH
  22.  
  23. #ifndef STREAMH
  24. #include <iostream.h>                // for iostream ops
  25. #define STREAMH
  26. #endif
  27.  
  28. #ifndef MISCELANEOUSH        // If we have not included this file,
  29. #include <misc.h>        // include miscelaneous useful definitions.
  30. #endif
  31.  
  32. class CoolValue {
  33. public:
  34.   CoolValue ();                    // empty constructor
  35.   CoolValue (const CoolValue&);            // copy constructor
  36.   inline ~CoolValue();                // destructor
  37.   
  38.   CoolValue& operator= (const CoolValue&);    // assignment
  39.   Boolean operator== (const CoolValue&) const;    // equality test
  40.   
  41.   inline CoolValue (char);            // char <-> Value
  42.   inline CoolValue& operator= (char);
  43.   inline operator char () const;    
  44.   
  45.   inline CoolValue (int);            // int <-> Value
  46.   inline CoolValue& operator= (int);
  47.   inline operator int () const;
  48.   
  49.   inline CoolValue (unsigned);            // unsigned <-> Value
  50.   inline CoolValue& operator= (unsigned);
  51.   inline operator unsigned () const;
  52.   
  53.   inline CoolValue (long);            // long <-> Value
  54.   inline CoolValue& operator= (long);
  55.   inline operator long () const;
  56.   
  57.   inline CoolValue (float);            // float <-> Value
  58.   inline CoolValue& operator= (float);
  59.   inline operator float () const;
  60.   
  61.   inline CoolValue (double);            // double <-> Value
  62.   inline CoolValue& operator= (double);
  63.   inline operator double () const;
  64.   
  65.   inline CoolValue (void*);            // void* <-> Value
  66.   inline CoolValue& operator= (void*);
  67.   inline operator void* () const;
  68.  
  69.   friend ostream& operator<< (ostream&, const CoolValue&); // output
  70.   /*inline##*/ friend ostream& operator<< (ostream&, const CoolValue*);
  71.  
  72. protected:
  73.   enum Type {                    // for correct print format
  74.     UNKNOWN = 0,                // and some run time type checking
  75.     CHAR,
  76.     INT,
  77.     UNSIGNED,
  78.     LONG,
  79.     FLOAT,
  80.     DOUBLE,
  81.     VOIDP
  82.     };
  83.   Type type;                
  84.   char data [8];                // enough to store anything
  85.  
  86.   void type_error (const char* fcn, Type t1, Type t2) const; // Raise exception
  87. };
  88.  
  89. // ~CoolValue()  -- Destructor
  90. // Input:   none
  91. // Output:  none
  92.  
  93. inline CoolValue::~CoolValue()          {}     // nothing needed
  94.  
  95. // CoolValue(Type)  -- Constructor from fundamental types: char, int, 
  96. //                 unsigned, long, float, double, void*, Generic*
  97. // Input:   char, number, or pointer
  98. // Ouput:   Value reference
  99.  
  100. // operator Type() -- Conversion to fundamental types.
  101. // Input:   Value reference
  102. // Output:  data of Value in fundamental type.
  103.  
  104. inline CoolValue::CoolValue (char c) 
  105. : type(CHAR) {
  106.   *((char *)this->data) = c;            // align with start of data
  107. }        
  108.  
  109. inline CoolValue& CoolValue::operator= (char c) {
  110.   if ((this->type == CHAR) || (this->type == UNKNOWN)) {
  111.     this->type = CHAR;
  112.     *((char *)this->data) = c;
  113.   } else 
  114.     this->type_error("operator=", this->type, CHAR);
  115.   return *this;
  116. }
  117.  
  118. inline CoolValue::operator char () const {
  119.   char c = 0;
  120.   switch (this->type) {
  121.   case CHAR:
  122.     c = *((char *)this->data); 
  123.     break;
  124.   default:
  125.     this->type_error("operator char",this->type, CHAR);
  126.     break;
  127.   }
  128.   return c;
  129. }    
  130.  
  131. inline CoolValue::CoolValue (unsigned u) 
  132. : type(UNSIGNED) { 
  133.   *((unsigned *) this->data) = u;
  134. }
  135.  
  136. inline CoolValue& CoolValue::operator= (unsigned u) {
  137.   if ((this->type == UNSIGNED) || (this->type == UNKNOWN)) {
  138.     this->type = UNSIGNED;
  139.     *((unsigned *)this->data) = u;
  140.   } else 
  141.     this->type_error("operator=", this->type, UNSIGNED);
  142.   return *this;
  143. }
  144.  
  145. inline CoolValue::operator unsigned () const {
  146.   unsigned u = 0;
  147.   switch (this->type) {
  148.   case CHAR:
  149.     u = *((char *) this->data); 
  150.     break;
  151.   case UNSIGNED:
  152.     u = *((unsigned *) this->data); 
  153.     break;
  154.   default:
  155.     this->type_error("operator unsigned", this->type, UNSIGNED);
  156.     break;
  157.   }
  158.   return u;
  159. }
  160.  
  161. inline CoolValue::CoolValue (int i) 
  162. : type(INT) {
  163.   *((int *) this->data) = i;
  164. }    
  165.  
  166. inline CoolValue& CoolValue::operator= (int i) {
  167.   if ((this->type == INT) || (this->type == UNKNOWN)) {
  168.     this->type = INT;
  169.     *((int *)this->data) = i;
  170.   } else 
  171.     this->type_error("operator=", this->type, INT);
  172.   return *this;
  173. }
  174.  
  175. inline CoolValue::operator int () const {
  176.   int i = 0;
  177.   switch (this->type) {
  178.   case CHAR:
  179.     i = *((char *) data); 
  180.     break;
  181.   case UNSIGNED:
  182.     i = *((unsigned *) data); 
  183.     break;
  184.   case INT:
  185.     i = *((int *) data); 
  186.     break;
  187.   default:
  188.     this->type_error("operator int",this->type, INT);
  189.     break;
  190.   }
  191.   return i;
  192. }
  193.  
  194. inline CoolValue::CoolValue (long l) 
  195. : type(LONG) {
  196.   *((long *) this->data) = l;
  197. }
  198.  
  199. inline CoolValue& CoolValue::operator= (long l) {
  200.   if ((this->type == LONG) || (this->type == UNKNOWN)) {
  201.     this->type = LONG;
  202.     *((long *)this->data) = l;
  203.   } else 
  204.     this->type_error("operator=", this->type, LONG);
  205.   return *this;
  206. }
  207.  
  208. inline CoolValue::operator long () const {
  209.   long l = 0;
  210.   switch (this->type) {
  211.   case CHAR:
  212.     l = *((char *) data); 
  213.     break;
  214.   case UNSIGNED:
  215.     l = *((unsigned *) data); 
  216.     break;
  217.   case INT:
  218.     l = *((int *) data); 
  219.     break;
  220.   case LONG:
  221.     l = *((long *) data); 
  222.     break;
  223.   default:
  224.     this->type_error("operator long",this->type, LONG);
  225.     break;
  226.   }
  227.   return l;
  228. }
  229.  
  230. inline CoolValue::CoolValue (float f) 
  231. : type(FLOAT) {
  232.   *((float *) this->data) = f; 
  233.  
  234. inline CoolValue& CoolValue::operator= (float f) {
  235.   if ((this->type == FLOAT) || (this->type == UNKNOWN)) {
  236.     this->type = FLOAT;
  237.     *((float *)this->data) = f;
  238.   } else 
  239.     this->type_error("operator=", this->type, FLOAT);
  240.   return *this;
  241. }
  242.  
  243. inline CoolValue::operator float () const { 
  244.   float f = 0;
  245.   switch (this->type) {
  246.   case CHAR:
  247.     f = *((char *) data); 
  248.     break;
  249.   case UNSIGNED:
  250.     f = *((unsigned *) data); 
  251.     break;
  252.   case INT:
  253.     f = *((int *) data);            // precision may be lost
  254.     break;
  255.   case LONG:
  256.     f = *((long *) data);            // precision may be lost
  257.     break;
  258.   case FLOAT:
  259.     f = *((float *) data); 
  260.     break;
  261.   case DOUBLE:
  262.     f = *((double *) data);            // precision may be lost
  263.     break;
  264.   case VOIDP:                    // avoid warning from CC
  265.   case UNKNOWN:
  266.   default:
  267.     this->type_error("operator float",this->type, FLOAT);
  268.     break;
  269.   }
  270.   return f;
  271. }
  272.  
  273. inline CoolValue::CoolValue (double d) 
  274. : type(DOUBLE) {
  275.   *((double *) this->data) = d; 
  276.  
  277. inline CoolValue& CoolValue::operator= (double d) {
  278.   if ((this->type == DOUBLE) || (this->type == UNKNOWN)) {
  279.     this->type = DOUBLE;
  280.     *((double *)this->data) = d;
  281.   } else 
  282.     this->type_error("operator=", this->type, DOUBLE);
  283.   return *this;
  284. }
  285.  
  286. inline CoolValue::operator double () const { 
  287.   double d = 0;
  288.   switch (this->type) {
  289.   case CHAR:
  290.     d = *((char *) data); 
  291.     break;
  292.   case UNSIGNED:
  293.     d = *((unsigned *) data); 
  294.     break;
  295.   case INT:
  296.     d = *((int *) data);            // precision may be lost
  297.     break;
  298.   case LONG:
  299.     d = *((long *) data);            // precision may be lost
  300.     break;
  301.   case FLOAT:
  302.     d = *((float *) data); 
  303.     break;
  304.   case DOUBLE:
  305.     d = *((double *) data);        
  306.     break;
  307.   case VOIDP:                    // avoid warning from CC
  308.   case UNKNOWN:
  309.   default:
  310.     this->type_error("operator double",this->type, DOUBLE);
  311.     break;
  312.   }
  313.   return d;
  314. }
  315.  
  316. inline CoolValue::CoolValue (void* v) 
  317. : type(VOIDP) { 
  318.   *((void **) this->data) = v; 
  319. }
  320.  
  321. inline CoolValue& CoolValue::operator= (void* d) {
  322.   if ((this->type == VOIDP) || (this->type == UNKNOWN)) {
  323.     this->type = VOIDP;
  324.     *((void* *)this->data) = d;
  325.   } else 
  326.     this->type_error("operator=", this->type, VOIDP);
  327.   return *this;
  328. }
  329.  
  330. inline CoolValue::operator void* () const {
  331.   void* v = NULL;
  332.   switch (this->type) {
  333.   case VOIDP:
  334.     v = *((void**) this->data); 
  335.     break;
  336.   default:
  337.     this->type_error("operator void*",this->type, VOIDP);
  338.     break;
  339.   }
  340.   return v;
  341. }
  342.  
  343.  
  344. // operator<<  -- Output value* to ostream
  345. // Input:    ostream, pointer to value
  346. // Output:   ostream reference
  347.  
  348. inline ostream& operator<< (ostream& os, const CoolValue* v) {
  349.   os << *v;
  350.   return os;
  351. }
  352.  
  353. #endif
  354.